﻿/*----------------------------------------------------------------
           // Copyright (C) 2008 RuleCode有限公司
           // 版权所有。 
           //
           // 文件名：SysCompiler.cs
           // 文件功能描述：系统编译功能。
           //
           // 
           // 创建标识：杨波20080912
           //
           // 修改标识
           // 修改描述：
           //
           // 修改标识：
           // 修改描述：
//----------------------------------------------------------------*/

#region UsingStatements

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using Microsoft.CSharp;
using RuleCode.ObjectTree;

#endregion

namespace RuleCode.compiler
{
    internal class SysCompiler
    {
        private static SysCompiler compiler;

        public static SysCompiler Instance
        {
            get
            {
                if (compiler == null)
                {
                    compiler = new SysCompiler();
                }
                return compiler;
            }
        }

        public void compileTable(SysTreeNode node)
        {
            SysCompilerTable.Instance.compileTable(node);
        }

        public void compileTables(SysTreeNode tables)
        {
            SysCompilerTable.Instance.compileTables(tables);
        }

        public void compileExtendDataType(SysTreeNode node)
        {
            SysCompilerEdt.Instance.compileExtendDataType(node);
        }

        public void compileEDTs(SysTreeNode edts)
        {
            SysCompilerEdt.Instance.compileEDTs(edts);
        }

        public void compileForm(SysTreeNode node)
        {
            SysCompilerForm.Instance.compileForm(node);
        }

        public void compileForms(SysTreeNode node)
        {
            SysCompilerForm.Instance.compileForms(node);
        }


        public void compileEnum(SysTreeNode node)
        {
            SysCompilerEnum.Instance.compileEnum(node);
        }

        public void compileEnums(SysTreeNode node)
        {
            SysCompilerEnum.Instance.compileEnums(node);
        }

        public void compileClass(SysTreeNode node)
        {
            SysCompilerClass.Instance.CompileClass(node);
        }

        public void compileClasses(SysTreeNode node)
        {
            SysCompilerClass.Instance.CompileClasses(node);
        }

        #region 公共函数 yujie.zhou

        //编译一组文件
        public static bool CompileCSharpCode(String[] sourceFile, String toFile)
        {
            //为啥要删?
            //编译前先手工删除原程序集
            FileInfo oldAssmbly = new FileInfo(toFile);
            if (oldAssmbly.Exists)
            {
                oldAssmbly.Delete();
            }
            CSharpCodeProvider provider = new CSharpCodeProvider();
            var csc = new CSharpCodeProvider(new Dictionary<string, string> { { "CompilerVersion", "v3.5" } });
            // Build the parameters for source compilation.
            CompilerParameters cp = new CompilerParameters();
            // Add an assembly reference.
            cp.ReferencedAssemblies.Add("System.dll");
            cp.ReferencedAssemblies.Add("System.Core.dll");
            cp.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
            cp.ReferencedAssemblies.Add("System.Xml.Linq.dll");
            //cp.ReferencedAssemblies.Add(@"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Core.dll");
            cp.ReferencedAssemblies.Add("System.Data.dll");
            //cp.ReferencedAssemblies.Add(@"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Data.DataSetExtensions.dll");
            cp.ReferencedAssemblies.Add("System.Deployment.dll");
            cp.ReferencedAssemblies.Add("System.Drawing.dll");
            cp.ReferencedAssemblies.Add("System.Xml.dll");
            //cp.ReferencedAssemblies.Add(@"C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.5\System.Xml.Linq.dll");
            cp.ReferencedAssemblies.Add("System.Windows.Forms.dll");



            DirectoryInfo basedir = new DirectoryInfo(Application.StartupPath);
            foreach (var fileInfo in basedir.GetFiles())
            {
                if (fileInfo.Name.EndsWith(".dll"))
                {
                    cp.ReferencedAssemblies.Add(fileInfo.Name);
                }
            }
            DirectoryInfo basedir1 = new DirectoryInfo(Util.GetLibPath);
            foreach (var fileInfo in basedir1.GetFiles())
            {
                if (fileInfo.Name.EndsWith(".dll"))
                {
                    if (fileInfo.FullName != toFile)
                        cp.ReferencedAssemblies.Add(fileInfo.FullName);
                }
            }





            // Generate an executable instead of 
            // a class library.
            cp.GenerateExecutable = false;

            // Set the assembly file name to generate.
            cp.OutputAssembly = toFile;

            // Save the assembly as a physical file.
            cp.GenerateInMemory = false;
            cp.WarningLevel = 1;

            cp.CompilerOptions = "/keyfile:" + "D:\\snk\\RuleCode.Query.snk";


            // Invoke compilation.
            CompilerResults cr = csc.CompileAssemblyFromFile(cp, sourceFile);

            if (cr.Errors.Count > 0)
            {
                Util.Info("Errors building " + sourceFile 
                    + " into" + cr.PathToAssembly);
                // Display compilation errors.
                Console.WriteLine("Errors building {0} into {1}",
                                  sourceFile, cr.PathToAssembly);
                foreach (CompilerError ce in cr.Errors)
                {
                    Util.Info(ce.ToString());
                    Console.WriteLine("  {0}", ce);
                    Console.WriteLine();
                }
            }
            else
            {
                Util.Info("Source " + sourceFile + " built into " 
                    + cr.PathToAssembly + " successfully.");
                Console.WriteLine("Source {0} built into {1} successfully.",
                                  sourceFile, cr.PathToAssembly);
            }

            // Return the results of compilation.
            if (cr.Errors.Count > 0)
            {
                return false;
            }
            else
            {

                return true;
            }
        }

        //编译一个文件夹,不包含子目录
        public static bool CompileCSharpCode(String _Directory, String toFile)
        {
            String[] sourceFile;
            DirectoryInfo DirectoryArray = new DirectoryInfo(_Directory);
            //获取该文件夹下的文件列表
            FileInfo[] Files = DirectoryArray.GetFiles("*.cs");
            sourceFile = new string[Files.Length];

            //遍历所有文件
            int i = 0;
            foreach (FileInfo inf in Files)
            {
                sourceFile[i] = inf.FullName;
                i++;
            }
            return CompileCSharpCode(sourceFile, toFile);
        }

        /// <summary>
        /// 编译很多文件夹,不包含子目录
        /// </summary>
        /// <param name="_Directories"></param>
        /// <param name="toFile"></param>
        /// <returns></returns>
        public static bool CompileCSharpCode2(String[] _Directories, String toFile)
        {
            List<string> list = new List<string>();
            foreach (string item in _Directories)
            {
                DirectoryInfo dir = new DirectoryInfo(item);
                FileInfo[] files = dir.GetFiles();
                foreach (var file in files)
                {
                    list.Add(file.FullName);
                }
            }
            CompileCSharpCode(list.ToArray(), toFile);
            return true;
        }

        #endregion
    }
}